package omm.domain.evolutiongraph;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import omm.domain.CommissionStrategy;
import omm.domain.Quotation;
import omm.domain.Quotation.State;

import org.apache.log4j.Logger;
import org.joda.time.DateTime;

public class ClientsQuantityUnitStrategy implements UnitStrategy {
	private static final Logger logger = Logger.getLogger(ClientsQuantityUnitStrategy.class);
	
	@Override
	public Map<DateTime, Double> calculateByPeriod(List<Quotation> quotations, PeriodStrategy periodStrategy,
			CommissionStrategy commition) {
		// Obtengo los periodos en cuestion
		Map<DateTime, Double> barsQuantity = periodStrategy.calculatePeriods();
		Map<DateTime, List<Quotation>> quotationsByPeriod = new LinkedHashMap<DateTime, List<Quotation>>();

		for (Entry<DateTime, Double> e : barsQuantity.entrySet()) {
			DateTime period = e.getKey();
			// Guardo en un map periodo y las quotations correspondientes
			quotationsByPeriod.put(period, filterQuotationsByStates(quotations, period, periodStrategy));
		}

		for (Entry<DateTime, List<Quotation>> quotationsByPeriodEntry : quotationsByPeriod.entrySet()) {
			// Por cada periodo
			DateTime period = quotationsByPeriodEntry.getKey();
			List<Quotation> filteredQuotations = quotationsByPeriodEntry.getValue();
			Iterator<Quotation> it = filteredQuotations.iterator();
			while (it.hasNext()) {
				Quotation q = it.next();

				if (commition.conditionToKeep(q.getState())) {
					DateTime modificationDate = q.getModificationDate();
					if (modificationDate != null) {
						for (Map.Entry<DateTime, Double> e : barsQuantity.entrySet()) {
							DateTime dateTime = e.getKey();
							// Comparo si pertenece al periodo
							if (periodStrategy.isInPeriod(modificationDate, dateTime)) {
								barsQuantity.put(period, barsQuantity.get(period) + 1);
								break;
							}
						}
					}
				}
			}
		}
		for (Entry<DateTime, Double> e : barsQuantity.entrySet()) {
			logger.debug("=========MES:" + e.getKey().getMonthOfYear() + " CANT:" + e.getValue());
		}
		return barsQuantity;
	}

	//TODO: Esto se repite un poco en QualityGraphic. Centralizarlo
	/***
	 * Calcula para cada entidad el estado que tiene segun sus cotizaciones
	 * 
	 * @return map ordenado por id de empresa con las cotizaciones con el estado
	 *         correspondiente de la empresa. con este resultado no se puede
	 *         sumar las comisiones, solo sirve para contar la cantidad de
	 *         empresas con determinado estado en determinado periodod de tiempo
	 */
	private List<Quotation> filterQuotationsByStates(List<Quotation> quotations, DateTime period, PeriodStrategy periodStrategy) {
		Map<Integer, State> entitiesStates = new LinkedHashMap<Integer, State>();
		Map<Integer, Quotation> quotationsByID = new LinkedHashMap<Integer, Quotation>();
		Iterator<Quotation> it = quotations.iterator();
		while (it.hasNext()) {
			Quotation q = it.next();
			if (periodStrategy.isInPeriod(q.getModificationDate(), period)) {
				try {
					Integer clientID = q.getOrder().getId();
					// Devuelve null si no se encuentra en el map
					State currentState = entitiesStates.get(clientID);
					// Si ya tenia estado de WON no me fijo porque ya esta
					// ganada
					if (currentState != State.WON) {
						if (((currentState == null) ||
								((currentState == State.LOST) || (currentState == State.QUOTED)) && (q.getState() == State.WON)) ||
								((currentState == State.QUOTED) && ((q.getState() == State.WON) || (q.getState() == State.LOST)))) {
							entitiesStates.put(clientID, q.getState());
							quotationsByID.put(clientID, q);
						}
					}
				} catch (Exception e) {
					// TODO:Loggear
				}
			}
		}
		return new ArrayList<Quotation>(quotationsByID.values());
	}

	@Override
	public Integer calculateMaxYAxis(Integer maxYAxis) {
		return maxYAxis;
	}

	@Override
	public String getTitle(CommissionStrategy commision) {
		return "Cantidad+de+clientes+" + commision.getName("ganados", "perdidos", "cotizados", "");
	}

}
